#if !defined( DEBUG_FUNC_H)
#define  DEBUG_FUNC_H
#include <string>
#include <ostream>
namespace
{
#ifndef DEBUG_LEVEL
# define DEBUG_LEVEL 0
#endif
struct t_debug_function
{
	enum {indent = 4};

	std::string	   			func_name;
	unsigned				priority;
	std::ostream&			ostrm;
	static unsigned 		recurse;
	static std::string		get_prefix() { return std::string(indent * (recurse), ' ');}
	static bool				show_debug(unsigned p) {return p <= DEBUG_LEVEL;}
	t_debug_function(std::ostream& os, unsigned i, const std::string& s)
			: func_name(s), priority(i), ostrm(os)
	{
		if (show_debug(priority))
			ostrm << (recurse ? std::string(indent * recurse, ' ') :std::string())
							<< func_name << " [entry]" << std::endl;
		++recurse;
	}
	~t_debug_function()
	{
		--recurse;
		if (show_debug(priority))
			ostrm << (recurse ? std::string(indent * recurse, ' ') :std::string())
							<< func_name << " [exit]" << std::endl;
	}
};

unsigned t_debug_function::recurse = 0;

#if (!defined(NDEBUG) || DEBUG_LEVEL > 9)
#define debug_func_cerr(ii) t_debug_function debug_function(std::cerr, ii, __func__)
#define debug_func_cout(ii) t_debug_function debug_function(std::cout, ii, __func__)
#define debug_prefix t_debug_function::get_prefix()
#define debug_show(ii) t_debug_function::show_debug(ii)
#define debug_cout(ii, text) if (debug_show(ii)){std::cout << debug_prefix << text << std::endl;}
#define debug_cerr(ii, text) if (debug_show(ii)){std::cerr << debug_prefix << text << std::endl;}
#else
#define debug_func_cerr(ii)
#define debug_func_cout(ii)
#define debug_prefix
#define debug_show(ii)
#define debug_cout(ii, text)
#define debug_cerr(ii, text)
#endif
}

#endif	//DEBUG_FUNC_H

